namespace C1.Win.C1FlexGrid
{
    using C1.Win.C1FlexGrid.Util.Styles;
    using System;
    using System.ComponentModel;
    using System.Drawing;

    public class GridTree
    {
        internal Brush _brush;
        internal bool _cancel;
        internal int _column;
        internal GridModel _grid;
        internal Image _imgCollapsed;
        internal Image _imgCollapsedUser;
        internal Image _imgExpanded;
        internal Image _imgExpandedUser;
        internal Size _imgSize;
        internal int _indent;
        internal Color _lineColor;
        internal TreeStyleFlags _style;

        internal GridTree(GridModel grid)
        {
            this._grid = grid;
            this._indent = 13;
            this._column = -1;
            this._lineColor = Color.DarkGray;
            this._imgSize = new Size(0, 0);
            this._style = TreeStyleFlags.Simple;
            this.Update(false);
        }

        internal void DrawButtonBar(Graphics g, C1.Win.C1FlexGrid.Util.Styles.Style s, Rectangle rc, string str, Image img)
        {
            Rectangle buttonRect;
            int num = this._grid._rows._maxNodeLevel;
            for (int i = 0; i <= num; i++)
            {
                buttonRect = this.GetButtonRect(rc, i);
                string str2 = string.Format("{0}", i + 1);
                s.Render(g, buttonRect, str2);
            }
            buttonRect = this.GetButtonRect(rc, num + 1);
            s.Render(g, buttonRect, "*");
            int num3 = buttonRect.Right - rc.X;
            if (num3 >= rc.Width)
            {
                num3 = rc.Width - 1;
            }
            rc.X += num3;
            rc.Width -= num3;
            s.Render(g, rc, str, img);
        }

        internal void DrawNode(C1FlexGridBase view, Graphics g, Rectangle rc, Node nd, int row)
        {
            int level = (nd != null) ? nd.Level : -1;
            Rectangle symbolRect = this.GetSymbolRect(rc, level);
            if (this.IsFlagSet(TreeStyleFlags.Lines))
            {
                RowCollection rows = this._grid._rows;
                bool flag = rows[row].IsNode;
                bool flag2 = flag && rows[row].Node.Collapsed;
                bool flag3 = level <= 0;
                bool flag4 = this.IsFlagSet(TreeStyleFlags.Leaf);
                bool flag5 = this._grid.SubtotalPosition == SubtotalPositionEnum.AboveData;
                int num2 = view.CheckNodeChildren(row, this.Column, level);
                bool flag6 = ((num2 & 2) != 0) || (flag4 && ((num2 & 1) != 0));
                Point point = new Point(symbolRect.X + (symbolRect.Width / 2), symbolRect.Y + (symbolRect.Height / 2));
                Point point2 = point;
                Point point3 = new Point(point.X + (this._indent / 2), point.Y);
                if (flag && !flag3)
                {
                    point2.X -= this._indent;
                    g.FillRectangle(this._brush, point2.X, point2.Y, point.X - point2.X, 1);
                    if (flag5)
                    {
                        g.FillRectangle(this._brush, point2.X, rc.Y, 1, point2.Y - rc.Y);
                    }
                    else
                    {
                        g.FillRectangle(this._brush, point2.X, point2.Y, 1, rc.Bottom - point2.Y);
                    }
                }
                else if (!flag && flag4)
                {
                    g.FillRectangle(this._brush, point2.X, point2.Y, point3.X - point2.X, 1);
                }
                if (flag || flag4)
                {
                    point2 = point3 = point;
                    if (flag5)
                    {
                        if (!flag)
                        {
                            point2.Y = rc.Y;
                        }
                        if (!flag2 && flag6)
                        {
                            point3.Y = rc.Bottom;
                        }
                    }
                    else
                    {
                        if (!flag)
                        {
                            point3.Y = rc.Bottom;
                        }
                        if (!flag2 && flag6)
                        {
                            point2.Y = rc.Y;
                        }
                    }
                    g.FillRectangle(this._brush, point2.X, point2.Y, 1, point3.Y - point2.Y);
                }
                int num3 = 0x2710;
                if (flag5)
                {
                    for (int i = row + 1; i < rows.Count; i++)
                    {
                        if (rows[i].IsNode)
                        {
                            int num5 = rows[i]._nodeLevel;
                            if (num5 <= 0)
                            {
                                break;
                            }
                            if (((num5 < num3) && (num5 <= (level + 1))) && (!flag || (num5 <= level)))
                            {
                                int x = ((rc.X + (num5 * this._indent)) - (this._indent / 2)) - 1;
                                g.FillRectangle(this._brush, x, rc.Y, 1, rc.Height);
                                num3 = num5;
                            }
                        }
                    }
                }
                else
                {
                    for (int j = row - 1; j >= rows.Fixed; j--)
                    {
                        if (rows[j].IsNode)
                        {
                            int num8 = rows[j]._nodeLevel;
                            if (num8 <= 0)
                            {
                                break;
                            }
                            if (((num8 < num3) && (num8 <= (level + 1))) && (!flag || (num8 <= level)))
                            {
                                int num9 = ((rc.X + (num8 * this._indent)) - (this._indent / 2)) - 1;
                                g.FillRectangle(this._brush, num9, rc.Y, 1, rc.Height);
                                num3 = num8;
                            }
                        }
                    }
                }
            }
            if (this.IsFlagSet(TreeStyleFlags.Symbols))
            {
                Image buttonImage = this.GetButtonImage(row);
                if (buttonImage != null)
                {
                    C1FlexGridBase._glyphStyle.Render(g, symbolRect, buttonImage);
                }
            }
        }

        internal Image GetButtonImage(int row)
        {
            Row row2 = this._grid._rows[row];
            if (!row2.IsNode)
            {
                return null;
            }
            Row row3 = null;
            bool flag = this._grid._subtotPos == SubtotalPositionEnum.AboveData;
            if (flag && (row < (this._grid._rows.Count - 1)))
            {
                row3 = this._grid._rows[row + 1];
            }
            if (!flag && (row > this._grid._rows.Fixed))
            {
                row3 = this._grid._rows[row - 1];
            }
            if (row3 == null)
            {
                return null;
            }
            if (row3.IsNode && (row3._nodeLevel <= row2._nodeLevel))
            {
                return null;
            }
            if (((short) (this._grid._rows[row]._flags & RowColFlags.Collapsed)) == 0)
            {
                return this._imgExpanded;
            }
            return this._imgCollapsed;
        }

        internal Rectangle GetButtonRect(Rectangle rc, int level)
        {
            Rectangle rectangle = new Rectangle(0, 0, 0, 0);
            if (level >= 0)
            {
                rectangle = rc;
                rectangle.X += level * this._indent;
                rectangle.Width = this._indent;
            }
            return rectangle;
        }

        internal int GetCellIndent(int row, int col)
        {
            if ((this.Column == col) && (row >= this._grid._rows.Fixed))
            {
                Node node = this._grid._rows[row].Node;
                if ((node != null) && (node.Level >= 0))
                {
                    return ((node.Level + 1) * this.Indent);
                }
            }
            return 0;
        }

        internal Node GetNode(Row row)
        {
            if (row.IsNode)
            {
                return new Node(row);
            }
            RowCollection rows = this._grid._rows;
            if (this._grid.SubtotalPosition == SubtotalPositionEnum.AboveData)
            {
                for (int i = row.Index; i >= 0; i--)
                {
                    if (rows[i].IsNode)
                    {
                        return new Node(rows[i]);
                    }
                }
            }
            else
            {
                for (int j = row.Index; j < rows.Count; j++)
                {
                    if (rows[j].IsNode)
                    {
                        return new Node(rows[j]);
                    }
                }
            }
            return null;
        }

        internal Rectangle GetSymbolRect(Rectangle rc, int level)
        {
            Rectangle rectangle = new Rectangle(0, 0, 0, 0);
            if (level >= 0)
            {
                rectangle.X = (rc.X + (level * this._indent)) + ((this._indent - this._imgSize.Width) / 2);
                rectangle.Y = rc.Y + ((rc.Height - this._imgSize.Height) / 2);
                rectangle.Width = this._imgSize.Width;
                rectangle.Height = this._imgSize.Height;
            }
            return rectangle;
        }

        internal int HandleKey(int row, MoveCursorEnum key)
        {
            if (!this._grid.IsBadCol(this.Column) && this.IsFlagSet(TreeStyleFlags.Symbols))
            {
                if (!this._grid._rows[row].IsNode)
                {
                    return row;
                }
                Node node = this._grid._rows[row].Node;
                if (node.Level < 0)
                {
                    return row;
                }
                if (key == MoveCursorEnum.CellLeft)
                {
                    if (!node.Collapsed)
                    {
                        node.Collapsed = true;
                        if (node.Collapsed)
                        {
                            return row;
                        }
                    }
                    node = node.GetNode(NodeTypeEnum.Parent);
                    if (node != null)
                    {
                        row = node.Row.Index;
                    }
                    return row;
                }
                if (key == MoveCursorEnum.CellRight)
                {
                    if (node.Collapsed)
                    {
                        node.Collapsed = false;
                        if (!node.Collapsed)
                        {
                            return row;
                        }
                    }
                    node = node.GetNode(NodeTypeEnum.FirstChild);
                    if (node != null)
                    {
                        row = node.Row.Index;
                    }
                }
            }
            return row;
        }

        internal bool IsFlagSet(TreeStyleFlags f)
        {
            return ((this._style & f) != TreeStyleFlags.None);
        }

        internal void SetIsNode(Row row, bool newVal)
        {
            if (row.IsNode != newVal)
            {
                row.SetFlags(RowColFlags.IsNode, newVal);
                row._coll.SetDirty();
                row._coll.Update();
                this._grid.NotifyViews(GridChangedTypeEnum.RepaintGrid);
            }
        }

        public bool ShouldSerializeLineColor()
        {
            return (this.LineColor != Color.DarkGray);
        }

        public bool ShouldSerializeNodeImageCollapsed()
        {
            return (this.NodeImageCollapsed != null);
        }

        public bool ShouldSerializeNodeImageExpanded()
        {
            return (this.NodeImageExpanded != null);
        }

        public bool ShouldSerializeStyle()
        {
            return (this.Style != TreeStyleFlags.Simple);
        }

        public void Show(int Level)
        {
            if (Level < 0)
            {
                Level = 0x7fffffff;
            }
            bool redraw = this._grid.Redraw;
            this._grid.Redraw = false;
            try
            {
                RowCollection rows = this._grid._rows;
                for (int i = rows.Fixed; i < rows.Count; i++)
                {
                    if (rows[i].IsNode)
                    {
                        int num2 = rows[i]._nodeLevel;
                        if ((num2 >= 0) && (num2 <= Level))
                        {
                            rows[i].Node.Collapsed = num2 == Level;
                        }
                    }
                }
            }
            finally
            {
                this._grid.Redraw = redraw;
            }
        }

        public void Sort(int level, SortFlags order, int col1, int col2)
        {
            bool redraw = this._grid.Redraw;
            this._grid.Redraw = false;
            try
            {
                RowCollection rows = this._grid._rows;
                for (int i = rows.Fixed; i < rows.Count; i++)
                {
                    if (rows[i].IsNode && (rows[i]._nodeLevel == level))
                    {
                        Node nd = rows[i].Node;
                        Node.SortSiblings(nd, order, col1, col2);
                        i = nd.GetNode(NodeTypeEnum.LastSibling).GetCellRange().r2;
                    }
                }
            }
            finally
            {
                this._grid.Redraw = redraw;
            }
        }

        internal int TreeWidth(int col)
        {
            if (this.Column != col)
            {
                return 0;
            }
            if (this.Style == TreeStyleFlags.None)
            {
                return 0;
            }
            int num = this._grid._rows._maxNodeLevel;
            if (num < 0)
            {
                return 0;
            }
            return (this.Indent * (num + 1));
        }

        internal void Update(bool notify)
        {
            try
            {
                this._imgCollapsed = this._imgCollapsedUser;
                this._imgExpanded = this._imgExpandedUser;
                if (this._imgCollapsed == null)
                {
                    this._imgCollapsed = C1FlexGridBase._glyphs[5];
                }
                if (this._imgExpanded == null)
                {
                    this._imgExpanded = C1FlexGridBase._glyphs[6];
                }
                this._imgSize.Width = Math.Max(this._imgCollapsed.Width, this._imgExpanded.Width);
                this._imgSize.Height = Math.Max(this._imgCollapsed.Height, this._imgExpanded.Height);
                if (this._indent < this._imgSize.Width)
                {
                    this._indent = this._imgSize.Width;
                }
                if (this._brush != null)
                {
                    this._brush.Dispose();
                }
                this._brush = new SolidBrush(this._lineColor);
                if (notify)
                {
                    this._grid.NotifyViews(GridChangedTypeEnum.RepaintGrid);
                }
            }
            catch (Exception)
            {

            }
        }

        [DefaultValue(-1)]
        public int Column
        {
            get
            {
                return this._column;
            }
            set
            {
                if (this._column != value)
                {
                    this._column = value;
                    this.Update(true);
                }
            }
        }

        [DefaultValue(13)]
        public int Indent
        {
            get
            {
                return this._indent;
            }
            set
            {
                this._indent = value;
                this.Update(true);
            }
        }

        public Color LineColor
        {
            get
            {
                return this._lineColor;
            }
            set
            {
                if (this._lineColor != value)
                {
                    this._lineColor = value;
                    this.Update(true);
                }
            }
        }

        [DefaultValue((string) null)]
        public Image NodeImageCollapsed
        {
            get
            {
                return this._imgCollapsedUser;
            }
            set
            {
                this._imgCollapsedUser = value;
                this.Update(true);
            }
        }

        [DefaultValue((string) null)]
        public Image NodeImageExpanded
        {
            get
            {
                return this._imgExpandedUser;
            }
            set
            {
                this._imgExpandedUser = value;
                this.Update(true);
            }
        }

        [DefaultValue(3)]
        public TreeStyleFlags Style
        {
            get
            {
                return this._style;
            }
            set
            {
                if (this._style != value)
                {
                    this._style = value;
                    this.Update(true);
                }
            }
        }
    }
}

